home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / C / CRACKLIB.ZIP / CRACKLIB.TAR / cracklib25_small / cracklib / packlib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-09  |  6.4 KB  |  357 lines

  1. /*
  2.  * This program is copyright Alec Muffett 1993. The author disclaims all 
  3.  * responsibility or liability with respect to it's usage or its effect 
  4.  * upon hardware or computer systems, and maintains copyright as set out 
  5.  * in the "LICENCE" document which accompanies distributions of Crack v4.0 
  6.  * and upwards.
  7.  */
  8.  
  9. #include "packer.h"
  10.  
  11. static char vers_id[] = "packlib.c : v2.3p2 Alec Muffett 18 May 1993";
  12.  
  13. PWDICT *
  14. PWOpen(prefix, mode)
  15.     char *prefix;
  16.     char *mode;
  17. {
  18.     int32 i;
  19.     static PWDICT pdesc;
  20.     char iname[STRINGSIZE];
  21.     char dname[STRINGSIZE];
  22.     char wname[STRINGSIZE];
  23.     char buffer[STRINGSIZE];
  24.     FILE *dfp;
  25.     FILE *ifp;
  26.     FILE *wfp;
  27.  
  28.     if (pdesc.header.pih_magic == PIH_MAGIC)
  29.     {
  30.     fprintf(stderr, "%s: another dictionary already open\n", prefix);
  31.     return ((PWDICT *) 0);
  32.     }
  33.  
  34.     memset(&pdesc, '\0', sizeof(pdesc));
  35.  
  36.     sprintf(iname, "%s.pwi", prefix);
  37.     sprintf(dname, "%s.pwd", prefix);
  38.     sprintf(wname, "%s.hwm", prefix);
  39.  
  40.     if (!(pdesc.dfp = fopen(dname, mode)))
  41.     {
  42.     perror(dname);
  43.     return ((PWDICT *) 0);
  44.     }
  45.  
  46.     if (!(pdesc.ifp = fopen(iname, mode)))
  47.     {
  48.     fclose(pdesc.dfp);
  49.     perror(iname);
  50.     return ((PWDICT *) 0);
  51.     }
  52.  
  53.     if (pdesc.wfp = fopen(wname, mode))
  54.     {
  55.     pdesc.flags |= PFOR_USEHWMS;
  56.     }
  57.  
  58.     ifp = pdesc.ifp;
  59.     dfp = pdesc.dfp;
  60.     wfp = pdesc.wfp;
  61.  
  62.     if (mode[0] == 'w')
  63.     {
  64.     pdesc.flags |= PFOR_WRITE;
  65.     pdesc.header.pih_magic = PIH_MAGIC;
  66.     pdesc.header.pih_blocklen = NUMWORDS;
  67.     pdesc.header.pih_numwords = 0;
  68.  
  69.     fwrite((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp);
  70.     } else
  71.     {
  72.     pdesc.flags &= ~PFOR_WRITE;
  73.  
  74.     if (!fread((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp))
  75.     {
  76.         fprintf(stderr, "%s: error reading header\n", prefix);
  77.  
  78.         pdesc.header.pih_magic = 0;
  79.         fclose(ifp);
  80.         fclose(dfp);
  81.         return ((PWDICT *) 0);
  82.     }
  83.  
  84.     if (pdesc.header.pih_magic != PIH_MAGIC)
  85.     {
  86.         fprintf(stderr, "%s: magic mismatch\n", prefix);
  87.  
  88.         pdesc.header.pih_magic = 0;
  89.         fclose(ifp);
  90.         fclose(dfp);
  91.         return ((PWDICT *) 0);
  92.     }
  93.  
  94.     if (pdesc.header.pih_blocklen != NUMWORDS)
  95.     {
  96.         fprintf(stderr, "%s: size mismatch\n", prefix);
  97.  
  98.         pdesc.header.pih_magic = 0;
  99.         fclose(ifp);
  100.         fclose(dfp);
  101.         return ((PWDICT *) 0);
  102.     }
  103.  
  104.     if (pdesc.flags & PFOR_USEHWMS)
  105.     {
  106.         if (fread(pdesc.hwms, 1, sizeof(pdesc.hwms), wfp) != sizeof(pdesc.hwms))
  107.         {
  108.         pdesc.flags &= ~PFOR_USEHWMS;
  109.         }
  110.     }
  111.     }
  112.  
  113.     return (&pdesc);
  114. }
  115.  
  116. int
  117. PWClose(pwp)
  118.     PWDICT *pwp;
  119. {
  120.     if (pwp->header.pih_magic != PIH_MAGIC)
  121.     {
  122.     fprintf(stderr, "PWClose: close magic mismatch\n");
  123.     return (-1);
  124.     }
  125.  
  126.     if (pwp->flags & PFOR_WRITE)
  127.     {
  128.     pwp->flags |= PFOR_FLUSH;
  129.     PutPW(pwp, (char *) 0);    /* flush last index if necess */
  130.  
  131.     if (fseek(pwp->ifp, 0L, 0))
  132.     {
  133.         fprintf(stderr, "index magic fseek failed\n");
  134.         return (-1);
  135.     }
  136.  
  137.     if (!fwrite((char *) &pwp->header, sizeof(pwp->header), 1, pwp->ifp))
  138.     {
  139.         fprintf(stderr, "index magic fwrite failed\n");
  140.         return (-1);
  141.     }
  142.  
  143.     if (pwp->flags & PFOR_USEHWMS)
  144.     {
  145.         int i;
  146.         for (i=1; i<=0xff; i++)
  147.         {
  148.             if (!pwp->hwms[i])
  149.             {
  150.                 pwp->hwms[i] = pwp->hwms[i-1];
  151.             }
  152. #ifdef DEBUG
  153.             printf("hwm[%02x] = %d\n", i, pwp->hwms[i]);
  154. #endif
  155.         }
  156.         fwrite(pwp->hwms, 1, sizeof(pwp->hwms), pwp->wfp);
  157.     }
  158.     }
  159.  
  160.     fclose(pwp->ifp);
  161.     fclose(pwp->dfp);
  162.  
  163.     pwp->header.pih_magic = 0;
  164.  
  165.     return (0);
  166. }
  167.  
  168. int
  169. PutPW(pwp, string)
  170.     PWDICT *pwp;
  171.     char *string;
  172. {
  173.     if (!(pwp->flags & PFOR_WRITE))
  174.     {
  175.     return (-1);
  176.     }
  177.  
  178.     if (string)
  179.     {
  180.     strncpy(pwp->data[pwp->count], string, MAXWORDLEN);
  181.     pwp->data[pwp->count][MAXWORDLEN - 1] = '\0';
  182.  
  183.     pwp->hwms[string[0] & 0xff]= pwp->header.pih_numwords;
  184.  
  185.     ++(pwp->count);
  186.     ++(pwp->header.pih_numwords);
  187.  
  188.     } else if (!(pwp->flags & PFOR_FLUSH))
  189.     {
  190.     return (-1);
  191.     }
  192.  
  193.     if ((pwp->flags & PFOR_FLUSH) || !(pwp->count % NUMWORDS))
  194.     {
  195.     int i;
  196.     int32 datum;
  197.     register char *ostr;
  198.  
  199.     datum = (int32) ftell(pwp->dfp);
  200.  
  201.     fwrite((char *) &datum, sizeof(datum), 1, pwp->ifp);
  202.  
  203.     fputs(pwp->data[0], pwp->dfp);
  204.     putc(0, pwp->dfp);
  205.  
  206.     ostr = pwp->data[0];
  207.  
  208.     for (i = 1; i < NUMWORDS; i++)
  209.     {
  210.         register int j;
  211.         register char *nstr;
  212.         nstr = pwp->data[i];
  213.  
  214.         if (nstr[0])
  215.         {
  216.         for (j = 0; ostr[j] && nstr[j] && (ostr[j] == nstr[j]); j++);
  217.         putc(j & 0xff, pwp->dfp);
  218.         fputs(nstr + j, pwp->dfp);
  219.         }
  220.         putc(0, pwp->dfp);
  221.  
  222.         ostr = nstr;
  223.     }
  224.  
  225.     memset(pwp->data, '\0', sizeof(pwp->data));
  226.     pwp->count = 0;
  227.     }
  228.     return (0);
  229. }
  230.  
  231. char *
  232. GetPW(pwp, number)
  233.     PWDICT *pwp;
  234.     int32 number;
  235. {
  236.     int32 datum;
  237.     register int i;
  238.     register char *ostr;
  239.     register char *nstr;
  240.     register char *bptr;
  241.     char buffer[NUMWORDS * MAXWORDLEN];
  242.     static char data[NUMWORDS][MAXWORDLEN];
  243.     static int32 prevblock = 0xffffffff;
  244.     int32 thisblock;
  245.  
  246.     thisblock = number / NUMWORDS;
  247.  
  248.     if (prevblock == thisblock)
  249.     {
  250.     return (data[number % NUMWORDS]);
  251.     }
  252.  
  253.     if (fseek(pwp->ifp, sizeof(struct pi_header) + (thisblock * sizeof(int32)), 0))
  254.     {
  255.     perror("(index fseek failed)");
  256.     return ((char *) 0);
  257.     }
  258.  
  259.     if (!fread((char *) &datum, sizeof(datum), 1, pwp->ifp))
  260.     {
  261.     perror("(index fread failed)");
  262.     return ((char *) 0);
  263.     }
  264.  
  265.     if (fseek(pwp->dfp, datum, 0))
  266.     {
  267.     perror("(data fseek failed)");
  268.     return ((char *) 0);
  269.     }
  270.  
  271.     if (!fread(buffer, 1, sizeof(buffer), pwp->dfp))
  272.     {
  273.     perror("(data fread failed)");
  274.     return ((char *) 0);
  275.     }
  276.  
  277.     prevblock = thisblock;
  278.  
  279.     bptr = buffer;
  280.  
  281.     for (ostr = data[0]; *(ostr++) = *(bptr++); /* nothing */ );
  282.  
  283.     ostr = data[0];
  284.  
  285.     for (i = 1; i < NUMWORDS; i++)
  286.     {
  287.     nstr = data[i];
  288.     strcpy(nstr, ostr);
  289.  
  290.     ostr = nstr + *(bptr++);
  291.     while (*(ostr++) = *(bptr++));
  292.  
  293.     ostr = nstr;
  294.     }
  295.  
  296.     return (data[number % NUMWORDS]);
  297. }
  298.  
  299. int32
  300. FindPW(pwp, string)
  301.     PWDICT *pwp;
  302.     char *string;
  303. {
  304.     register int32 lwm;
  305.     register int32 hwm;
  306.     register int32 middle;
  307.     register char *this;
  308.     int idx;
  309.  
  310.     if (pwp->flags & PFOR_USEHWMS)
  311.     {
  312.     idx = string[0] & 0xff;
  313.         lwm = idx ? pwp->hwms[idx - 1] : 0;
  314.         hwm = pwp->hwms[idx];
  315.     } else
  316.     {
  317.         lwm = 0;
  318.         hwm = PW_WORDS(pwp) - 1;
  319.     }
  320.  
  321. #ifdef DEBUG
  322.     printf("---- %lu, %lu ----\n", lwm, hwm);
  323. #endif
  324.  
  325.     for (;;)
  326.     {
  327.     int cmp;
  328.  
  329. #ifdef DEBUG
  330.     printf("%lu, %lu\n", lwm, hwm);
  331. #endif
  332.  
  333.     middle = lwm + ((hwm - lwm + 1) / 2);
  334.  
  335.     if (middle == hwm)
  336.     {
  337.         break;
  338.     }
  339.  
  340.     this = GetPW(pwp, middle);
  341.     cmp = strcmp(string, this);        /* INLINE ? */
  342.  
  343.     if (cmp < 0)
  344.     {
  345.         hwm = middle;
  346.     } else if (cmp > 0)
  347.     {
  348.         lwm = middle;
  349.     } else
  350.     {
  351.         return (middle);
  352.     }
  353.     }
  354.  
  355.     return (PW_WORDS(pwp));
  356. }
  357.